package com.xiyuan.smartutils;

import com.xiyuan.smartutils.constants.CodeConstants;
import com.xiyuan.smartutils.constants.SignConstants;
import com.xiyuan.smartutils.reflect.Unsafe;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;

/**
 * 随机访问文件工具类
 *
 * @version v1.0.0 @author lgz 2017-9-21 新建与整理
 */

@SuppressWarnings({"unused", "AlibabaLowerCamelCaseVariableNaming"})
public final class RAFiles implements SignConstants, CodeConstants {
    static {
        Unsafe.init();
    }
    private RAFiles() {}
    /*************************************************************/
    //创建RandomAccessFile对象，异常返回null
    /*************************************************************/
    
    /**
     * 新建随机访问文件，异常时返回null
     *
     * @param file 文件
     * @param mode 模式，=r表示只读，=w表示只写，=rw表示读写,=rws表示读写同步，=rwd表示动态读写同步
     * @return RandomAccessFile
     */
    public static RandomAccessFile newFile(File file, String mode) {
        try {return new RandomAccessFile(file, mode);}catch (Throwable e) {return null;}
    }
    
    /**
     * 新建随机访问只读文件，异常时返回null
     *
     * @param file 文件
     * @return RandomAccessFile
     */
    public static RandomAccessFile newFileR(File file) {
        try {return new RandomAccessFile(file, _RO_);}catch (Throwable e) {return null;}
    }
    
    /**
     * 新建随机访问读写文件，异常时返回null
     *
     * @param file 文件
     * @return RandomAccessFile
     */
    public static RandomAccessFile newFileRW(File file) {
        try {return new RandomAccessFile(file, _RW_);}catch (Throwable e) {return null;}
    }
    
    /**
     * 新建随机访问文件，异常时返回null
     *
     * @param filePath 文件路径
     * @param mode     模式，=r表示只读，=w表示只写，=rw表示读写,=rws表示读写同步，=rwd表示动态读写同步
     * @return RandomAccessFile
     */
    public static RandomAccessFile newFile(String filePath, String mode) {
        try {return new RandomAccessFile(filePath, mode);}catch (Throwable e) {return null;}
    }
    
    /**
     * 新建随机访问只读文件，异常时返回null
     *
     * @param filePath 文件路径
     * @return RandomAccessFile
     */
    public static RandomAccessFile newFileR(String filePath) {
        try {return new RandomAccessFile(filePath, _RO_);}catch (Throwable e) {return null;}
    }
    
    /**
     * 新建随机访问读写文件，异常时返回null
     *
     * @param filePath 文件路径
     * @return RandomAccessFile
     */
    public static RandomAccessFile newFileRW(String filePath) {
        try {return new RandomAccessFile(filePath, _RW_);}catch (Throwable e) {return null;}
    }
    
    /*************************************************************/
    //处理RandomAccessFile对象，异常返回null
    /*************************************************************/
    
    /**
     * 关闭随机访问文件
     *
     * @param file 访问文件
     */
    public static void close(RandomAccessFile file) {
        Closes.closeIgnoreException(file);
    }
    
    /**
     * 读取文件数据
     *
     * @param file 文件
     * @param pos  文件位置
     * @param len  读取长度
     * @return 返回指定长度的数据
     */
    public static String readUTF8(RandomAccessFile file, long pos, int len) {
        try {
            byte[] b = read(file, pos, len);
            return new String(b, StandardCharsets.UTF_8);
        }
        catch (IOException e) {
            return null;
        }
    }
    
    /**
     * 读取文件数据
     *
     * @param file 文件
     * @param pos  文件位置
     * @param len  读取长度
     * @return 返回指定长度的数据
     * @throws IOException 异常
     */
    public static byte[] read(RandomAccessFile file, long pos, int len) throws IOException {
        byte[] b = new byte[len];
        file.seek(pos);
        file.read(b);
        
        return b;
    }
    
    /**
     * 读取可能的文件数据到指定的字节数组
     *
     * @param file 文件
     * @param pos  文件位置
     * @param buf  传入的字节数组
     * @param off  传入字节数组偏移
     * @param len  读取长度
     * @return 读取数目
     * @throws IOException 异常
     */
    public static int readMaybe(RandomAccessFile file, long pos, byte[] buf, int off, int len) throws IOException {
        return Files.readMaybe(file.getChannel(), pos, buf, off, len);
    }
    
    /**
     * 写入文件数据
     *
     * @param file 文件
     * @param pos  文件位置
     * @param b    数据
     * @throws IOException 异常
     */
    public static void write(RandomAccessFile file, long pos, byte[] b) throws IOException {
        file.seek(pos);
        file.write(b);
    }
    
    /**
     * 写入文件数据到文件尾端
     *
     * @param file 文件
     * @param b    数据
     * @throws IOException 异常
     */
    public static void write(RandomAccessFile file, byte[] b) throws IOException {
        file.seek(file.length());
        file.write(b);
    }
    
    /**
     * 写入字符串到文件指定位置
     *
     * @param file    文件
     * @param pos     文件位置
     * @param content 内容
     * @return =true表示写入成功
     */
    public static boolean writeUTF8(RandomAccessFile file, long pos, String content) {
        try {
            file.seek(pos);
            file.write(content.getBytes(StandardCharsets.UTF_8));
            return true;
        }
        catch (IOException e) {
            return false;
        }
        
    }
}
